package com.rgh.pecunia.core.dao;

import java.util.List;
import java.util.Map;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;
import com.rgh.pecunia.core.DataAccessObject;
import com.rgh.pecunia.domain.Account;
import com.rgh.pecunia.domain.BusinessEntity;
import com.rgh.pecunia.domain.Transfer;

public class ObjectifyDAO implements DataAccessObject {

    // Initialize entities
    static {
        ObjectifyService.register(Account.class);
        ObjectifyService.register(Transfer.class);
    }
    
    // Serial version UID
    private static final long serialVersionUID = 1L;
    
    // Objectify interface
    private transient Objectify objectify;

    @Override
    public Objectify ofy() {
        if (objectify == null) {
            objectify = ObjectifyService.begin();
        }
        return objectify;
    }

    @Override
    public <O extends BusinessEntity> O get(Key<O> key) {
        return ofy().get(key);
    }

    @Override
    public <O extends BusinessEntity> O find(Class<O> clazz, Long id) {
        return ofy().find(clazz, id);
    }

    @Override
    public <O extends BusinessEntity> Query<O> query(Class<O> clazz) {
        return ofy().query(clazz);
    }

    @Override
    public <O extends BusinessEntity> List<Key<O>> keys(Class<O> clazz) {
        return ofy().query(clazz).listKeys();
    }

    @Override
    public <O extends BusinessEntity> Query<O> query(Class<O> clazz, String criteria, Object value) {
        return ofy().query(clazz).filter(criteria, value);
    }

    @Override
    public <O extends BusinessEntity> List<Key<O>> keys(Class<O> clazz, String criteria, Object value) {
        return ofy().query(clazz).filter(criteria, value).listKeys();
    }

    @Override
    public <O extends BusinessEntity> Query<O> query(Class<O> clazz, Map<String, Object> criterion) {
        Query<O> query = ofy().query(clazz);
        for (String key : criterion.keySet()) {
            query = query.filter(key, criterion.get(key));
        }
        return query;
    }

    @Override
    public <O extends BusinessEntity> List<Key<O>> keys(Class<O> clazz, Map<String, Object> criterion) {
        Query<O> query = ofy().query(clazz);
        for (String key : criterion.keySet()) {
            query = query.filter(key, criterion.get(key));
        }
        return query.listKeys();
    }

    @Override
    public <O extends BusinessEntity> void put(O entity) {
        ofy().put(entity);
    }

    @Override
    public <O extends BusinessEntity> void delete(O entity) {
        ofy().delete(entity);
    }
}
